package mcore

import (
	"database/sql/driver"
	"fmt"
	"strings"
	"time"
)

type String string

func (domain *String) String() string {
	return string(*domain)
}

func (domain *String) Value() (driver.Value, error) {
	return domain.String(), nil
}

func (domain *String) Scan(src any) error {
	switch src.(type) {
	case []uint8:
		*domain = String(string(src.([]uint8)))
		return nil
	case time.Time:
		*domain = String((src.(time.Time)).String())
		return nil
	default:
		*domain = String(fmt.Sprintf("%v", src))
		return nil
	}
}

func (domain *String) Int64() int64 {
	s := domain.String()
	if i := strings.Index(s, "."); i != -1 {
		return Strings.ToInt64(s[0:i])
	}
	return Strings.ToInt64(domain)
}

func (domain *String) Int8() int8 {
	s := domain.String()
	if i := strings.Index(s, "."); i != -1 {
		return Strings.ToInt8(s[0:i])
	}
	return Strings.ToInt8(domain)
}
func (domain *String) Int() int {
	s := domain.String()
	if i := strings.Index(s, "."); i != -1 {
		return Strings.ToInt(s[0:i])
	}
	return Strings.ToInt(domain)
}
func (domain *String) Int32() int32 {
	s := domain.String()
	if i := strings.Index(s, "."); i != -1 {
		return Strings.ToInt32(s[0:i])
	}
	return Strings.ToInt32(domain)
}

func (domain *String) Int16() int16 {
	s := domain.String()
	if i := strings.Index(s, "."); i != -1 {
		return Strings.ToInt16(s[0:i])
	}
	return Strings.ToInt16(domain)
}

func (domain *String) Bool() bool {
	return Strings.ToBool(domain)
}

func (domain *String) Float32() float32 {
	return Strings.ToFloat32(domain)
}

func (domain *String) Float64() float64 {
	return Strings.ToFloat64(domain)
}

func (domain *String) IsEmpty() bool {
	return domain == nil || len(*domain) == 0
}

func (domain *String) Length() int {
	return len(*domain)
}

func (domain *String) EqualFold(val string) bool {
	return strings.EqualFold(domain.String(), val)
}

func (domain *String) HasSuffix(suffix string) bool {
	return strings.HasSuffix(domain.String(), suffix)
}

func (domain *String) HasPrefix(prefix string) bool {
	return strings.HasPrefix(domain.String(), prefix)
}

func (domain *String) Index(substr string) int {
	return strings.Index(domain.String(), substr)
}

func (domain *String) IndexAny(chars string) int {
	return strings.IndexAny(domain.String(), chars)
}

func (domain *String) LastIndex(substr string) int {
	return strings.LastIndex(domain.String(), substr)
}

func (domain *String) LastIndexAny(chars string) int {
	return strings.LastIndexAny(domain.String(), chars)
}
func (domain *String) Time() time.Time {
	length := len(*domain)
	if length == 8 {
		return DateUtil.StrToTime(domain.String())
	} else if length == 10 {
		return DateUtil.StrToDate(domain.String())
	} else if length == 19 || length == 27 {
		return DateUtil.StrToDateTime(domain.String())
	} else if length == 29 || length == 37 {
		date := (*domain)[0:19]
		return DateUtil.StrToDateTime(date.String())
	}
	panic(fmt.Sprintf("%s is not a valid date format !", domain.String()))
}
func (domain *String) LocalDateTime() LocalDatetime {
	return LocalDatetime(domain.Time())
}
func (domain *String) UnmarshalJSON(data []byte) (err error) {
	*domain = *StringReadByte(data)
	return
}
func StringReadByte(data []byte) *String {
	length := len(data)
	if length >= 2 {
		if data[0] == 34 && data[length-1] == 34 {
			data = data[1 : length-1]
		}
	}
	result := String(data)
	return &result
}
func StringReadString(data string) *String {
	return StringReadByte([]byte(data))
}
